﻿using Common;
using Common.Enums;
using enterprise.Website.Core.Filter;
using FreeSql.Context;
using FreeSql.Model;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;


namespace enterprise.Website.Core.ApiControllers
{
    /// <summary>
    /// 产品管理
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [LoginAuthorize]
    public class ProductController : ControllerBase
    {
        private readonly SqlContext _sqlContext;
        private readonly ICache _cache;
        private readonly IWebHostEnvironment _hostingEnvironment;
        public ProductController(SqlContext sqlContext,
            ICache cache,
            IWebHostEnvironment hostingEnvironment)
        {
            _cache = cache;
            _sqlContext = sqlContext;
            _hostingEnvironment = hostingEnvironment;
        }

        /// <summary>
        /// 产品列表
        /// </summary>
        /// <param name="casNo"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<PageModel<Product_Info>> Get(int? languageId, string casNo, int page = 1, int limit = 10)
        {
            Expression<Func<Product_Info, LanguageType, ContentClass, bool>> where = (t, t1, t2) => true;
            if (!casNo.IsNullOrWhiteSpace())
            {
                where = where.And((t, t1, t2) => t.CasNo == casNo);
            }
            if (languageId.HasValue)
            {
                where = where.And((t, t1, t2) => t.LanguageId == languageId);
            }
            long Count = 0;
            var list = await _sqlContext.DB.Select<Product_Info, LanguageType, ContentClass>()
                .LeftJoin((t, t1, t2) => t.LanguageId == t1.Id)
                .LeftJoin((t, t1, t2) => t.ClassId == t2.Id)
                .Where(where)
                .Page(page, limit)
                .Count(out Count)
                .OrderByDescending((t, t1, t2) => t.Sort)
                .ToListAsync((t, t1, t2) => new Product_Info
                {
                    Id = t.Id,
                    ProName = t.ProName,
                    CasNo = t.CasNo,
                    MolecularFormula = t.MolecularFormula,
                    Sort = t.Sort,
                    ClassName = t2.ClassName,
                    LanguageName = t1.Language,
                    ClassId = t.ClassId,
                    LanguageId = t.LanguageId,
                    IsShow = t.IsShow
                });
            //计算总页数
            int pageCount = (Math.Ceiling(Count.ObjToDecimal() / limit.ObjToDecimal())).ObjToInt();
            //获取标题图片
            list.ForEach(m =>
            {
                var ProTitleImg = _sqlContext.QueryInfo<Product_Img>(n => n.ProId == m.Id, "IsTitle Desc");
                if (ProTitleImg != null)
                {
                    m.TitleImg = ProTitleImg.Img;
                }
            });
            return new PageModel<Product_Info>
            {
                count = Count,
                data = list,
                PageSize = limit,
                PageCount = pageCount,
                PageIndex = page,
                code = Count == 0 ? -1 : 0,
                msg = Count == 0 ? "暂无数据" : ""
            };
        }

        /// <summary>
        /// 获取产品详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<ApiResult<Product_Info>> GetInfo(int id = 0)
        {
            var result = new ApiResult<Product_Info> { Success = false, Message = "查询失败" };
            if (id > 0)
            {
                var productinfo = await _sqlContext.QueryInfoAsync<Product_Info>(m => m.Id == id);
                if (productinfo != null)
                {
                    productinfo.ProductImgs = await _sqlContext.QueryListAsync<Product_Img>(m => m.ProId == id, "IsTitle desc");
                    result.Data = productinfo;
                    result.Success = true;
                    result.Message = "查询成功";
                }
            }
            return result;
        }

        /// <summary>
        /// 新增产品
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<int>> Post([FromBody] Product_Info data)
        {
            var result = new ApiResult<int> { Success = false, Message = "保存失败" };
            if (data != null)
            {
                var Id = await _sqlContext.AddAsync(data);
                if (Id > 0)
                {
                    //如果有产品图片，则进行图片保存
                    if (data.ProductImgs != null && data.ProductImgs.Count > 0)
                    {
                        var proImgs = data.ProductImgs.Select(m => new Product_Img
                        {
                            Id = 0,
                            IsTitle = m.IsTitle,
                            Img = m.Img,
                            ProId = Id.ObjToInt()
                        }).ToList();
                        await _sqlContext.AddListAsync<Product_Img>(proImgs);
                    }
                    result.Success = true;
                    result.Message = "保存成功";
                    result.Data = Id.ObjToInt();
                    _cache.Remove($"{SystemConstConfig.Products}_{data.LanguageId}");
                }
            }
            return result;
        }

        /// <summary>
        /// 新增产品
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task<ApiResult> Put(int id = 0, [FromBody] Product_Info data = null)
        {
            var result = new ApiResult { Success = false, Message = "保存失败" };
            if (data != null && id > 0)
            {
                data.Id = id;
                var Count = await _sqlContext.UpdateAsync(data);
                if (Count > 0)
                {
                    //如果有产品图片，则进行图片保存
                    if (data.ProductImgs != null && data.ProductImgs.Count > 0)
                    {
                        data.ProductImgs.ForEach(m =>
                        {
                            //Id为0说明是新上传的图片
                            if (m.Id == 0)
                            {
                                m.ProId = id;
                                _sqlContext.Add(m);
                            }
                            else
                            {
                                _sqlContext.Update<Product_Img>(n => new Product_Img
                                {
                                    IsTitle = m.IsTitle
                                }, l => l.Id == m.Id);
                            }
                        });
                    }
                    result.Success = true;
                    result.Message = "保存成功";
                    _cache.Remove($"{SystemConstConfig.Products}_{data.LanguageId}");
                }
            }
            return result;
        }

        /// <summary>
        /// 删除产品图片
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("DeleteProductImg")]
        public async Task<ApiResult> DeleteProductImg([FromForm] int? id)
        {
            var result = new ApiResult { Success = false, Message = "删除失败" };
            if (id.HasValue)
            {
                var productImgInfo = await _sqlContext.QueryInfoAsync<Product_Img>(m => m.Id == id.Value);
                if (productImgInfo != null)
                {
                    var Count = await _sqlContext.DeleteAsync<Product_Img>(m => m.Id == id);
                    if (Count > 0)
                    {
                        result.Success = true;
                        result.Message = "删除成功";
                        RemoveProductCache();
                        var root = _hostingEnvironment.WebRootPath;
                        var filePath = root + productImgInfo.Img;
                        if (System.IO.File.Exists(filePath))
                        {
                            System.IO.File.Delete(filePath);
                        }

                    }
                }
            }
            return result;
        }


        /// <summary>
        /// 删除产品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<ApiResult> Delete([FromBody] List<int> ids = null)
        {
            var result = new ApiResult { Success = false, Message = "删除失败" };
            if (ids != null)
            {
                var Count = await _sqlContext.DeleteAsync<Product_Info>(m => ids.Contains(m.Id));
                if (Count > 0)
                {
                    result.Success = true;
                    result.Message = "删除成功";
                    RemoveProductCache();
                    //如果有图片，就删除产品图片
                    var productImgs = await _sqlContext.QueryListAsync<Product_Img>(m => ids.Contains(m.ProId));
                    var imgIds = productImgs.Select(m => m.Id).ToArray();
                    if (productImgs != null)
                    {
#pragma warning disable CS4014 // 由于此调用不会等待，因此在调用完成前将继续执行当前方法
                        Task.Run(() => 
                        {
                            var proImgs = productImgs;
                            var root = _hostingEnvironment.WebRootPath;
                            foreach (var img in proImgs)
                            {
                                var filePath = root + img.Img;
                                if (System.IO.File.Exists(filePath))
                                {
                                    System.IO.File.Delete(filePath);
                                }
                            }
                        });
#pragma warning restore CS4014 // 由于此调用不会等待，因此在调用完成前将继续执行当前方法
                        await _sqlContext.DeleteAsync<Product_Img>(m => imgIds.Contains(m.Id));
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 修改产品排序
        /// </summary>
        /// <returns></returns>
        [HttpPut("SetProductSort")]
        public async Task<ApiResult> SetProductSort([FromForm] int id = 0, [FromForm] string sort = "")
        {
            var result = new ApiResult { Success = false, Message = "保存失败" };
            if (id > 0)
            {
                int? sortNum = sort.ToInt32();
                if (!sortNum.HasValue)
                {
                    result.Message = "请输入正确的数字";
                    return result;
                }
                var Count = await _sqlContext.UpdateAsync<Product_Info>(m => new Product_Info
                {
                    Sort = sortNum.Value
                }, n => n.Id == id);
                if (Count > 0)
                {
                    result.Message = "保存成功";
                    result.Success = true;
                    RemoveProductCache();
                }
            }
            return result;
        }

        /// <summary>
        /// 上传需求单Excel表格
        /// </summary>
        /// <returns></returns>
        [HttpPost("UploadExcel")]
        public ApiResult<List<Product_Info>> UploadExcel()
        {
            var result = new ApiResult<List<Product_Info>>() { Success = false, Message = "请求失败" };
            var ExcelFile = Request.Form.Files[0];
            var Sheet = NPOITool.ReadExcalSheet(ExcelFile);
            if (Sheet != null)
            {
                var dataList = new List<Product_Info>();
                var rowCount = Sheet.LastRowNum;
                for (int i = 2; i <= rowCount; i++)
                {
                    var Info = new Product_Info();
                    var Row = Sheet.GetRow(i);
                    Info.ProName = Convert.ToString(Row.GetCell(0));
                    Info.ClassName = Convert.ToString(Row.GetCell(1));
                    Info.ProNo = Convert.ToString(Row.GetCell(2));
                    Info.CasNo = Convert.ToString(Row.GetCell(3));
                    Info.SeoKeywords = Convert.ToString(Row.GetCell(4));
                    Info.SeoDescription = Convert.ToString(Row.GetCell(5));
                    Info.Sort = Convert.ToString(Row.GetCell(6)).ToInt32(0);
                    Info.MolecularFormula = Convert.ToString(Row.GetCell(7));
                    Info.Molecularweight = Convert.ToString(Row.GetCell(8));
                    Info.Purity = Convert.ToString(Row.GetCell(9));
                    Info.Meltingpoint = Convert.ToString(Row.GetCell(10));
                    Info.Packaging = Convert.ToString(Row.GetCell(11));
                    Info.Appearance = Convert.ToString(Row.GetCell(12));
                    Info.ProductionCapacity = Convert.ToString(Row.GetCell(13));
                    Info.Productuse = Convert.ToString(Row.GetCell(14));
                    Info.DeliveryTime = Convert.ToString(Row.GetCell(15));
                    Info.IsShow = Convert.ToString(Row.GetCell(16)).ToInt32(0);
                    dataList.Add(Info);
                }
                result.Data = dataList;
                result.Message = "请求成功";
                result.Success = true;
            }
            return result;
        }

        /// <summary>
        /// 产品导入
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost("AddProducts")]
        public async Task<ApiResult<List<Product_Info>>> AddProducts([FromBody] List<Product_Info> data)
        {
            var result = new ApiResult<List<Product_Info>> { Success = false, Message = "导入失败" };
            var errorProduct = new List<Product_Info>();
            var needImgProudcts = new List<Product_Info>();
            if (data != null && data.Count > 0)
            {
                data.ForEach(m =>
                {
                    if (!m.ClassName.IsNullOrWhiteSpace())
                    {
                        var ClassInfo = _sqlContext.QueryInfo<ContentClass>(n => n.ClassName == m.ClassName.Trim());
                        if (ClassInfo != null && ClassInfo.ClassType == (int)ClassType.Products)
                        {
                            m.ClassId = ClassInfo.Id;
                            m.LanguageId = ClassInfo.LanguageId;
                        }
                        else
                        {
                            var enLan = _sqlContext.QueryInfo<LanguageType>(m => m.LanguageClass.Contains("en"));
                            if (enLan == null)
                            {
                                enLan = _sqlContext.QueryInfo<LanguageType>();
                            }
                            var TopClassInfo = _sqlContext.QueryInfo<ContentClass>(n => n.ClassType == (int)ClassType.Products && n.ParentId == 0 && n.LanguageId == enLan.Id);
                            _sqlContext.Add(new ContentClass
                            {
                                ClassType = (int)ClassType.Products,
                                IsShow = 0,
                                ClassName = m.ClassName,
                                ParentId = TopClassInfo.Id,
                                LanguageId = enLan.Id
                            });
                            _cache.Remove($"{SystemConstConfig.ContentClassKey}_{enLan.Id}");
                        }
                    }
                    else
                    {
                        var enLan = _sqlContext.QueryInfo<LanguageType>(orderBy: "IsDefault desc");
                        if (enLan != null)
                        {
                            m.LanguageId = enLan.Id;
                            m.ClassId = 0;
                        }
                    }
                    if (!m.CasNo.IsNullOrWhiteSpace())
                    {
                        //如果是正确的Cas号，录入，否则提醒并不录入
                        if (m.CasNo.IsCasNo())
                        {
                            var Id = _sqlContext.Add(m);
                            if (Id > 0)
                            {
                                m.Id = Id.ObjToInt();
                                needImgProudcts.Add(m);
                            }
                        }
                        else
                        {
                            errorProduct.Add(m);
                        }
                    }
                    else
                    {
                        _sqlContext.Add(m);
                    }
                });
                if (errorProduct.Count <= 0)
                {
                    result.Success = true;
                    result.Message = "导入成功";
                }
                else
                {
                    result.Success = false;
                    result.Data = errorProduct;
                    result.Message = "部分导入成功，下列产品监测到Cas号填写错误，请填写正确的Cas号或者去除其Cas号";
                }
                RemoveProductCache();
            }
            //另启线程，拉取结构式
            if (needImgProudcts.Count > 0)
            {
#pragma warning disable CS4014 // 由于此调用不会等待，因此在调用完成前将继续执行当前方法
                Task.Run(() =>
                {
                    string saveRoute = AppSetting.UploadRoute;
                    string rootPath = Path.Combine(_hostingEnvironment.WebRootPath, saveRoute);
                    var pros = needImgProudcts;
                    foreach (var m in pros)
                    {
                        var fileName = Guid.NewGuid().ToString() + ".gif";
                        var isSuccess = HttpHelp.HttpDownLoadFile($"https://www.chemicalbook.com/CAS/GIF/{m.CasNo}.gif", rootPath, fileName);
                        if (isSuccess > 0)
                        {
                            _sqlContext.Add<Product_Img>(new Product_Img
                            {
                                ProId = m.Id,
                                Img = Path.Combine("/" + saveRoute, fileName),
                                IsTitle = 0
                            });
                        }
                    }
                });
#pragma warning restore CS4014 // 由于此调用不会等待，因此在调用完成前将继续执行当前方法
            }
            return result;
        }

        /// <summary>
        /// 删除产品缓存
        /// </summary>
        private void RemoveProductCache()
        {
            var Lantypes = _sqlContext.QueryList<LanguageType>();
            if (Lantypes != null && Lantypes.Count > 0)
            {
                foreach (var item in Lantypes)
                {
                    _cache.Remove($"{SystemConstConfig.Products}_{item.Id}");
                }
            }
        }
    }
}
